home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / db / esm-3.1 / esm-3 / usr / local / sm / src / serverlib / undo / undoLHash.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-05  |  13.5 KB  |  453 lines

  1. /* $RCSfile: undoLHash.C,v $
  2.  * $Revision: 1.1.1.1 $
  3.  * $Date :$
  4.  */
  5. /**********************************************************************
  6. * EXODUS Database Toolkit Software
  7. * Copyright (c) 1991 Computer Sciences Department, University of
  8. *                    Wisconsin -- Madison
  9. * All Rights Reserved.
  10. *
  11. * Permission to use, copy, modify and distribute this software and its
  12. * documentation is hereby granted, provided that both the copyright
  13. * notice and this permission notice appear in all copies of the
  14. * software, derivative works or modified versions, and any portions
  15. * thereof, and that both notices appear in supporting documentation.
  16. *
  17. * THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY OF WISCONSIN --
  18. * MADISON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION.  
  19. * THE DEPARTMENT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
  20. * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  21. *
  22. * The EXODUS Project Group requests users of this software to return 
  23. * any improvements or extensions that they make to:
  24. *
  25. *   EXODUS Project Group 
  26. *     c/o David J. DeWitt and Michael J. Carey
  27. *   Computer Sciences Department
  28. *   University of Wisconsin -- Madison
  29. *   Madison, WI 53706
  30. *
  31. *     or exodus@cs.wisc.edu
  32. *
  33. * In addition, the EXODUS Project Group requests that users grant the 
  34. * Computer Sciences Department rights to redistribute these changes.
  35. **********************************************************************/
  36. #include "BTREEPAGE.h"
  37. #include "LHDIRPAGE.h"
  38. #include "BT_Tuple.h"
  39. #include "LH_Log.h"
  40. #ifdef INIT_LRC_IS_LSN
  41. #   include "log_globals.h"
  42. #endif
  43.  
  44. extern void (*LH_PrintFunc)(int len, char* key);
  45.  
  46. #ifdef DEBUG_LHASH
  47. static void IntPrint(int /* kLen */, char* key)
  48. {
  49.     printf("%d", *((int*) key));
  50. }
  51. #endif
  52.  
  53.  
  54. void undoLHash(LOGRECORDHDR* recHdr)
  55. {
  56.     undoLHash_fr(recHdr);
  57. }
  58.  
  59. void undoLHash_fr(LOGRECORDHDR* recHdr)
  60. {
  61. #ifdef INIT_LRC_IS_LSN
  62.     LRC                 tempLRC;
  63.     LRC                 *lrc = &tempLRC;
  64. #else
  65.     LRC                 *lrc;
  66. #endif /* INIT_LRC_IS_LSN; */
  67.  
  68.     TRPRINT(TR_IO, TR_LEVEL_1, ("lsn:%d", recHdr->recordLSN));
  69.  
  70.     TRANSREC* transRec = (TRANSREC*) Active->transRec;
  71.     INIT_MISSING_UPDATE_INFO( transRec );
  72.  
  73.     PID* pid = &recHdr->actionPid;
  74.     TRPRINT(TR_IO|TR_LOG, TR_LEVEL_2, ("pid:%d", pid->page));
  75.  
  76.     GROUPLINK* groupLink = bf_ReadPage(UserBufGroup, pid, 
  77.                                         BTREE_PAGE2SIZE, BF_SEM);
  78.  
  79.     LHINDPAGE* indp = (LHINDPAGE*) groupLink->bufFrame;
  80.     BOOL actionDone = compareLRC( &recHdr->actionLRC, &(indp->lrc())) <= 0;
  81.  
  82. #ifndef INIT_LRC_IS_LSN
  83.     SM_ASSERT(LEVEL_3, missingUpdateInfo != NULL);
  84. #endif
  85.  
  86.     RECORD_MISSING_UPDATE(actionDone, &lrc, missingUpdateInfo, pid, 
  87.                         & indp->lrc(), groupLink->pageHash, recHdr,
  88.                         PAGE_INDEX);
  89.  
  90.     if (lrc != & indp->lrc())      GENERATE_LRC(lrc);
  91.  
  92.     LSNOFFSET undoNextLSN = recHdr->previousLSN;
  93.  
  94.     signalSemaphore( & groupLink->pageHash->semaphore);
  95.     
  96.     void* vptr = GET_LOG_IMAGE(recHdr, 0);
  97.     LH_TRACE(("U(%d,%d,%c): ", recHdr->recordLSN.offset, pid->page, 
  98.                     actionDone ? 't' : 'f'));
  99.     PAGEHASH* pHash = actionDone ? groupLink->pageHash : 0;
  100.         
  101.     switch (recHdr->action)  {
  102.         int i;
  103.         
  104.         case LOG_ACTION_LHASH_PHYSIC_INSERT:
  105.             {
  106.             LogLhashPhysicInsertData* rp = (LogLhashPhysicInsertData*) vptr;
  107.             ASSERT3(rp->startSlot >= 0 && rp->numSlots > 0);
  108.             LH_TRACE(("undo physic insert\n"));
  109.  
  110.             if (actionDone)  {
  111.                 for (i = rp->startSlot + rp->numSlots - 1;
  112.                                     i >= rp->startSlot; i--)  {
  113.                     indp->RemoveTuple(i);
  114.                     }
  115.                 }
  116.             LH_LogPhysicDelete(indp->SelfID(), pHash, *lrc,
  117.                                     rp->startSlot, rp->numSlots, 
  118.                                     (int)rp->length, rp->data);
  119.             }
  120.             break;
  121.         case LOG_ACTION_LHASH_PHYLOG_INSERT:
  122.             {
  123.             LogLhashPhyLogInsertData* rp = (LogLhashPhyLogInsertData*) vptr;
  124.             ASSERT3(rp->numSlots > 0);
  125.             LH_TRACE((" undo physiologic insert\n"));
  126.             TWO slot;
  127.             PFC func = SMCOMPFUNC[indp->KeyType()];
  128.             if (actionDone)  {
  129.                 char* buff = rp->data;
  130.                 for (i = rp->numSlots - 1;
  131.                                     i >= 0; i--)  {
  132.                     BT_Tuple* tp = (BT_Tuple*) buff;
  133.                     if (!indp->Search(tp->KeyLen(), tp->KeyValue(), func,slot)) {
  134.                         ASSERT3(FALSE);
  135.                         }
  136.                     else {
  137.                         indp->RemoveTuple(slot);
  138.                         }
  139.                     buff += tp->Size();
  140.                     }
  141.                 }
  142.             LH_LogPhyLogDelete(indp->SelfID(), pHash, *lrc, rp->numSlots,
  143.                                     (int)rp->length, rp->data);
  144.             }
  145.             break;
  146.         case LOG_ACTION_LHASH_PHYSIC_DELETE:
  147.             {
  148.             LogLhashPhysicDeleteData* rp = (LogLhashPhysicDeleteData*) vptr;
  149.             ASSERT3(rp->startSlot >= 0 && rp->numSlots > 0);
  150.             LH_TRACE((" undo physic delete\n"));
  151.             if (actionDone)  {
  152.                 char* buff = rp->data;
  153.                 for (i = rp->startSlot; i < rp->startSlot+rp->numSlots; i++)  {
  154.                     BT_Tuple* tp = (BT_Tuple*) buff;
  155.                     indp->InsertTuple(*tp, i);
  156.                     buff += tp->Size();
  157.                     }
  158.                 ASSERT3(buff - rp->data <= rp->length);
  159.                 }
  160.             LH_LogPhysicInsert(indp->SelfID(), pHash, *lrc,
  161.                                 rp->startSlot, rp->numSlots, 
  162.                                 (int)rp->length, rp->data);
  163.             }
  164.             break;
  165.         case LOG_ACTION_LHASH_PHYLOG_DELETE:
  166.             {
  167.             LogLhashPhyLogDeleteData* rp = (LogLhashPhyLogDeleteData*) vptr;
  168.             ASSERT3(rp->numSlots > 0);
  169.             LH_TRACE((" undo physiologic delete\n"));
  170.             TWO slot;
  171.             PFC func = SMCOMPFUNC[indp->KeyType()];
  172.             if (actionDone)  {
  173.                 char* buff = rp->data;
  174.                 for (i = 0; i < rp->numSlots; i++)  {
  175.                     BT_Tuple* tp = (BT_Tuple*) buff;
  176.                     if (indp->Search(tp->KeyLen(), tp->KeyValue(), func,slot)) {
  177.                         ASSERT3(FALSE);
  178.                         }
  179.                     else {
  180.                         indp->InsertTuple(*tp, slot);
  181.                         }
  182.                     buff += tp->Size();
  183.                     }
  184.                 }
  185.             LH_LogPhyLogInsert(indp->SelfID(), pHash, *lrc, rp->numSlots,
  186.                                     (int)rp->length, rp->data);
  187.             }
  188.             break;
  189.             
  190.         case LOG_ACTION_LHASH_LOGIC_INSERT:
  191.             {
  192.             LogLhashLogicInsertData* rp = (LogLhashLogicInsertData*) vptr;
  193.             LH_TRACE((" undo logic insert %d\n", * (int*) rp->Key()));
  194.             if (actionDone)  {
  195.                 if (lh_RemoveEntry(transRec->tid, rp->rootPid, UserBufGroup,
  196.                                     rp->Key(), rp->keyLen, rp->elSize, 
  197.                                     rp->El(), rp->maxKeyLen, rp->unique,
  198.                                     SMCOMPFUNC[rp->keyType], !rp->primary)) {
  199.                     SM_ERROR(TYPE_FATAL, esmINTERNAL);
  200.                     }
  201.                 }
  202.             else    {
  203.                 LH_LogLogicDelete(indp->SelfID(), pHash, *lrc,
  204.                                     rp->rootPid, rp->Key(), rp->keyLen,
  205.                                     rp->El(), rp->elSize, rp->maxKeyLen,
  206.                                     rp->unique, rp->keyType, rp->primary);
  207.                 }
  208.             }
  209.             actionDone = FALSE;    /* assume action not done on this page */
  210.             break;
  211.         
  212.         case LOG_ACTION_LHASH_LOGIC_DELETE:
  213.             {
  214.             LogLhashLogicDeleteData* rp = (LogLhashLogicDeleteData*) vptr;
  215.             LH_TRACE((" undo logic delete %d\n", * (int*) rp->Key()));
  216.             if (actionDone)  {
  217.                 if (lh_InsertEntry(transRec->tid, rp->rootPid, UserBufGroup,
  218.                                     rp->Key(), rp->keyLen, rp->elSize, 
  219.                                     rp->El(), rp->maxKeyLen, rp->unique,
  220.                                     SMCOMPFUNC[rp->keyType], !rp->primary))  {
  221.                     SM_ERROR(TYPE_FATAL, esmINTERNAL);
  222.                     }
  223.                 }
  224.             else    {
  225.                 LH_LogLogicInsert(indp->SelfID(), pHash, *lrc,
  226.                                     rp->rootPid, rp->Key(), rp->keyLen,
  227.                                     rp->El(), rp->elSize, rp->maxKeyLen,
  228.                                     rp->unique, rp->keyType, rp->primary);
  229.                 }
  230.             }
  231.             actionDone = FALSE;    /* assume action not done on this page */
  232.             break;
  233.         case LOG_ACTION_LHASH_SET_INDEX_OVERFLOW:
  234.             {
  235.             LogSetIndexOverflowData* rp = (LogSetIndexOverflowData*) vptr;
  236.             BOOL keepFlag = (rp->oldOvPage != NULLPID);
  237.             if (actionDone) {
  238.                 indp->SetPageOverflow(rp->oldOvPage);
  239.                 indp->ResetPageOverflow(keepFlag);
  240.                 }
  241.             LH_LogResetIndexOverflow(indp->SelfID(), pHash, *lrc,
  242.                                      rp->oldOvPage, keepFlag);
  243.             }
  244.             break;
  245.         case LOG_ACTION_LHASH_RESET_INDEX_OVERFLOW:
  246.             {
  247.             LogResetIndexOverflowData* rp = (LogResetIndexOverflowData*) vptr;
  248.             SHORTPID newOvPage = indp->OvPage();
  249.  
  250.             if (actionDone) {
  251.                 indp->SetPageOverflow(rp->oldOvPage);
  252.                 }
  253.             LH_LogSetIndexOverflow(indp->SelfID(), pHash, *lrc,
  254.                                     rp->oldOvPage, newOvPage);
  255.             }
  256.             break;
  257.         case LOG_ACTION_LHASH_DIR_UPDATE:
  258.             {
  259.             LHDIRPAGE* dirp = (LHDIRPAGE*) groupLink->bufFrame;
  260.             LogDirUpdateData* rp = (LogDirUpdateData*) vptr;
  261.             if (actionDone) {
  262.                 if (rp->growFlag)
  263.                     dirp->IndShrinkUpdate(rp->fromLoad, rp->toLoad,
  264.                                             rp->oldFromLoad);
  265.                 else
  266.                     dirp->IndSplitUpdate(rp->oldFromLoad, rp->fromLoad,
  267.                                             rp->toLoad);
  268.                 }
  269.             LH_LogDirUpdate(dirp->SelfID(), pHash, *lrc, rp->oldFromLoad,
  270.                                     rp->fromLoad, rp->toLoad, !rp->growFlag);
  271.             }
  272.             break;
  273.         case LOG_ACTION_LHASH_DIR_SPLIT_RESET:
  274.             {
  275.             LHDIRPAGE* dirp = (LHDIRPAGE*) groupLink->bufFrame;
  276.             LogDirSplitData* rp = (LogDirSplitData*) vptr;
  277.             if (actionDone) {
  278.                 dirp->lhDirCtrl.height = (ONE) rp->height;
  279.                 dirp->lhDirCtrl.curPos = rp->curPos;
  280.                 BCOPY(rp->data, dirp->indPid,
  281.                                     (int)rp->curPos*sizeof(SHORTPID));
  282.                 }
  283.             LH_LogDirSplitCopy(dirp->SelfID(), pHash, *lrc, 
  284.                                     (int) rp->height, (int) rp->curPos);
  285.             }
  286.             break;
  287.         case LOG_ACTION_LHASH_DIR_LOAD_UPDATE:
  288.             {
  289.             LHDIRPAGE* dirp = (LHDIRPAGE*) groupLink->bufFrame;
  290.             LogDirLoadUpdateData* rp = (LogDirLoadUpdateData*) vptr;
  291.             if (actionDone) {
  292.                 dirp->LoadUpdate(rp->load2,rp->load1);
  293.                 }
  294.             LH_LogDirLoadUpdate(dirp->SelfID(), pHash, *lrc, 
  295.                                     rp->load2, rp->load1);
  296.             }
  297.             break;
  298.         case LOG_ACTION_LHASH_DIR_SET_NEXT_ENTRY:
  299.             {
  300.             LHDIRPAGE* dirp = (LHDIRPAGE*) groupLink->bufFrame;
  301.             LogDirSetNextEntryData* rp = (LogDirSetNextEntryData*) vptr;
  302.             LH_TRACE(("undo root set next entry, hashval %d\n", rp->hashVal));
  303.             if (actionDone) {
  304.                 dirp->UnSetNextEntry(rp->hashVal);
  305.                 }
  306.             LH_LogDirSetNextEntry(dirp->SelfID(), pHash, *lrc, NULLPID-1, rp->hashVal);
  307.             }
  308.             break;
  309.         case LOG_ACTION_LHASH_SET_THRESHOLD:
  310.             {
  311.             LHDIRPAGE* dirp = (LHDIRPAGE*) groupLink->bufFrame;
  312.             LogSetThresholdData* rp = (LogSetThresholdData*) vptr;
  313.             if (actionDone) {
  314.                 dirp->SetThreshold(rp->oldThreshold);
  315.                 }
  316.             LH_LogSetThreshold(dirp->SelfID(), pHash, *lrc,
  317.                                 rp->newThreshold, rp->oldThreshold);
  318.             }
  319.             break;
  320.         case LOG_ACTION_LHASH_DIR_ROOT_CTRL:
  321.             {
  322.             LHDIRPAGE* dirp = (LHDIRPAGE*) groupLink->bufFrame;
  323.             LogDirRootCtrlData* rp = (LogDirRootCtrlData*) vptr;
  324.             PRINT_PROGRESS(("undo root ctrl: pid %d\n", dirp->SelfID().page));
  325.             if (actionDone) {
  326.                 dirp->lhDirCtrl.M = rp->M;
  327.                 dirp->lhDirCtrl.P = rp->P;
  328.                 dirp->lhDirCtrl.I = rp->I;
  329.                 dirp->lhDirCtrl.curPos = rp->curPos;
  330.                 dirp->lhDirCtrl.height = rp->height;
  331.                 dirp->lhDirCtrl.load = rp->load;
  332.                 for (i=0;i<INIT_PRIMARY;i++) 
  333.                     dirp->SetEntry(NULLPID,i);
  334.                 }
  335.             LH_LogDirRootCtrl(dirp->SelfID(), pHash, *lrc, FALSE);
  336.             for (i=0;i<INIT_PRIMARY;i++)
  337.                  LH_LogDirSetNextEntry(dirp->SelfID(), pHash, *lrc,
  338.                                          NULLPID, i);
  339.             }
  340.             break;
  341.         case LOG_ACTION_LHASH_LOGIC_INCR_OIDCNT:
  342.             {
  343.             LogLhashLogicIncrElCntData* rp =
  344.                 (LogLhashLogicIncrElCntData*) vptr;
  345.             LH_TRACE(("undo ++elemcnt\n"));
  346.  
  347.             if (actionDone)  {
  348.                 if (LH_DecrElCnt(transRec->tid, rp->rootPid, UserBufGroup,
  349.                     rp->key, rp->keyLen, rp->maxKeyLen,
  350.                     SMCOMPFUNC[rp->keyType])){
  351.                     SM_ERROR(TYPE_FATAL, esmINTERNAL);
  352.                     }
  353.                 }
  354.             else {
  355.                 LH_LogLogicDecrElCnt(indp->SelfID(), pHash, *lrc,
  356.                                         rp->rootPid,
  357.                                         rp->key, rp->keyLen, rp->maxKeyLen,
  358.                                         rp->keyType);
  359.                 }
  360.             }
  361.             actionDone = FALSE; /* assume action not done on this page */
  362.             break;
  363.         case LOG_ACTION_LHASH_LOGIC_DECR_OIDCNT:
  364.             {
  365.             LogLhashLogicDecrElCntData* rp =
  366.                 (LogLhashLogicDecrElCntData*) vptr;
  367.             LH_TRACE((" undo --elemcnt\n"));
  368.             if (actionDone)  {
  369.                 if (LH_IncrElCnt(transRec->tid, rp->rootPid, UserBufGroup,
  370.                                     rp->key, rp->keyLen, rp->maxKeyLen,
  371.                                     SMCOMPFUNC[rp->keyType])){
  372.                     SM_ERROR(TYPE_FATAL, esmINTERNAL);
  373.                     }
  374.                 }
  375.             else {
  376.                 LH_LogLogicIncrElCnt(indp->SelfID(), pHash, *lrc,
  377.                                         rp->rootPid,
  378.                                         rp->key, rp->keyLen, rp->maxKeyLen,
  379.                                         rp->keyType);
  380.                 }
  381.             }
  382.             actionDone = FALSE; /* assume action not done on this page */
  383.             break;
  384.         case LOG_ACTION_LHASH_LOGIC_SET_OVERFLOW:
  385.             {
  386.             LogLhashLogicSetOverflowData* rp =
  387.                 (LogLhashLogicSetOverflowData*) vptr;
  388.             LH_TRACE(("undo set overflow\n"));
  389.             if (actionDone)  {
  390.                 if (LH_ResetOverflow(transRec->tid, rp->rootPid, UserBufGroup,
  391.                                         rp->KeyValue(), rp->keyLen,
  392.                                         rp->maxKeyLen, SMCOMPFUNC[rp->keyType],
  393.                                         rp->ElList(), rp->numEl))  {
  394.                     SM_ERROR(TYPE_FATAL, esmINTERNAL);
  395.                     }
  396.                 }
  397.             else {
  398.                 LH_LogLogicResetOverflow(indp->SelfID(), pHash,
  399.                                         *lrc, rp->rootPid,
  400.                                         rp->KeyValue(), rp->keyLen,
  401.                                         rp->maxKeyLen, rp->keyType,
  402.                                         rp->numEl, rp->elSize, 
  403.                                         rp->ElList(), rp->ovPid);
  404.                 }
  405.             }
  406.             actionDone = FALSE; /* assume action not done on this page */
  407.             break;
  408.         case LOG_ACTION_LHASH_LOGIC_RESET_OVERFLOW:
  409.             {
  410.             LogLhashLogicResetOverflowData* rp =
  411.                 (LogLhashLogicResetOverflowData*) vptr;
  412.             LH_TRACE(("undo reset overflow\n"));
  413.             if (actionDone)  {
  414.                 if (LH_SetOverflow(transRec->tid, rp->rootPid, UserBufGroup,
  415.                                         rp->KeyValue(), rp->keyLen,
  416.                                         rp->maxKeyLen, SMCOMPFUNC[rp->keyType],
  417.                                         rp->ElList(), rp->elSize, rp->numEl))  {
  418.                     SM_ERROR(TYPE_FATAL, esmINTERNAL);
  419.                     }
  420.                 }
  421.             else {
  422.                 LH_LogLogicSetOverflow(indp->SelfID(), pHash, *lrc,
  423.                                         rp->rootPid, rp->KeyValue(),
  424.                                         rp->keyLen, rp->maxKeyLen, rp->keyType,
  425.                                         rp->numEl, rp->elSize, rp->ElList(),
  426.                                         rp->ovPid);
  427.                 }
  428.             }
  429.             actionDone = FALSE; /* assume action not done on this page */
  430.             break;
  431.         case LOG_ACTION_LHASH_OV_CONVERT:
  432.             {
  433.             LogLhashOvConvertData* rp =
  434.                 (LogLhashOvConvertData*) vptr;
  435.             LH_TRACE(("undo convert overflow\n"));
  436.             if (actionDone)  {
  437.                 indp->OvConvert(rp->oldHashVal, FALSE);
  438.                 }
  439.             LH_LogOvConvert(indp->SelfID(), pHash, *lrc, rp->newHashVal,
  440.                             rp->oldHashVal, FALSE);
  441.             }
  442.             break;
  443.         default:                
  444.             SM_ERROR(TYPE_FATAL, esmINTERNAL);
  445.         }
  446.  
  447.     LH_LogPureCLR(undoNextLSN);
  448.     LH_TRACE(("CLR %d\n", undoNextLSN));
  449.     bf_UnfixPage(groupLink, BF_DEFAULT, actionDone);
  450. }
  451.  
  452.  
  453.